package main

import "fmt"

const (
	// 方向
	dY = iota
	dX
	_dY
	_dX

	// 行为
	L = 'L' // 左转
	R = 'R' // 右转
	F = 'F' // 前进
	B = 'B' // 后退

	f  = 1  // 前进指令值
	b  = -1 // 后退指令值
	tr = 1  // 右转指令值
	tl = -1 // 左转指令值
)

type Robot struct {
	Direction int8   // 机器人方向:Y 0   X 1  -Y 2  -X 3
	Locate    Locate // 机器人坐标
}

type Locate struct {
	X int
	Y int
}

// 创建机器人
func NewRobot() *Robot {
	return &Robot{}
}

// Turn 转向
func (r *Robot) turn(cmd byte) *Robot {
	switch cmd {
	case L:
		r.Direction = (r.Direction + tl + 4) % 4
	case R:
		r.Direction = (r.Direction + tr + 4) % 4
	}
	return r
}

func (r *Robot) getDirection() string {
	switch r.Direction {
	case dY:
		return "+Y"
	case dX:
		return "+X"
	case _dY:
		return "-Y"
	case _dX:
		return "-X"
	default:
		return "睡着了"
	}

}

// Move 移动
func (r *Robot) move(cmd byte) *Robot {
	switch {
	case r.Direction == dY && cmd == F || r.Direction == _dY && cmd == B:
		r.Locate.Y += f
	case r.Direction == dX && cmd == F || r.Direction == _dX && cmd == B:
		r.Locate.X += f
	case r.Direction == _dY && cmd == F || r.Direction == dY && cmd == B:
		r.Locate.Y += b
	case r.Direction == _dX && cmd == F || r.Direction == dX && cmd == B:
		r.Locate.X += b
	}
	return r
}

// Action 行动
func (r *Robot) action(cmds []byte) *Robot {
	for _, cmd := range cmds {
		switch cmd {
		case L, R:
			r.turn(cmd)
		case F, B:
			r.move(cmd)
		}
	}
	return r
}

func (r *Robot) report() {
	fmt.Printf("报告：坐标：（%d,%d)，面向：%s \n",
		r.Locate.X, r.Locate.Y, r.getDirection())
}

func (r *Robot) Action(cmdStr string) error {
	cmds, err := instructionParser(cmdStr)
	if err != nil {
		return err
	}

	r.action(cmds).report()
	return nil
}

//instructionParser 指令解析器  指令可以为：FFR2(LFRF)FFRB —— 括号中的数据表示执行数字次
func instructionParser(cmdStr string) ([]byte, error) {
	// todo 待完善
	return []byte(cmdStr), nil
}

func main() {
	cmds := "FFFLBBRFFF"
	err := NewRobot().Action(cmds)
	if err != nil {
		fmt.Println(err)
	}
}
